﻿using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;


namespace FinalProjectLogicLayer
{
    class HtmlReport
    {
        public static void createReport(String filepath,String title,Dictionary dictionary, int stringMatchingDistance, Clustering.DistanceMeasurement distance, int numberOfClusters, String clusteringMethod,ArrayList clusteringResults)
        {
            //String filePath, Dictionary dictionary, int stringMatchingDistance, Clustering.DistanceMeasurement distance, int NumberOfClusters, String clusteringMethod,int numberOfClusters    
            TextWriter tw = new StreamWriter(filepath);
            String imagePath = filepath.Substring(filepath.LastIndexOf('\\')+1)+"\\";
            imagePath = imagePath.Substring(0, imagePath.LastIndexOf('.')) + '\\';
            //tw.WriteLine(DateTime.Now);
            String htmlStart = "<html>\n<head>\n" + createStyle() + "\n\t<title>" + title + "</title>\n</head><body>\n";
            String htmlEnd = "\n</body></html>";
            String fileLegend = "<BR>List of files in the process (numbers match graphs):<BR><OL>" + htmlListOfFiles(clusteringResults) + "</OL>";
            String htmlTitle = "<CENTER><h1>Cipher text analysis using csv's</h1><BR><h2>Clustering Report</h2></CENTER>\n";
            htmlTitle += "<CENTER><BR>" + DateTime.Now + "</CENTER>\n";
            String clusteringResultImage = "<center><img class=\"IMAGE\" src=\" " + imagePath + "CLUSTERING_RESULT.jpg\"></center><br>\n";
            String htmlClusteringSettings = settingsHtmlString(dictionary,stringMatchingDistance,distance,numberOfClusters,clusteringMethod);
            String htmlClusteringResults = clustersHTML(imagePath,clusteringResults);
            String htmlDocument = htmlStart + htmlTitle + clusteringResultImage + lastCalculatedResultsHtmlTabel +htmlClusteringSettings + fileLegend + htmlClusteringResults + htmlEnd;
            tw.WriteLine(htmlDocument);
            // close the stream
            tw.Close(); 
        }
        
        /// <summary>
        /// This method creates a HTML REPORT File
        /// </summary>
        /// <param name="filepath">filePath(filename) to be saved</param>
        /// <param name="xmlRootElementId">root elemnts name</param>
        private static String createStyle()
        {
            String style = "";
            style += "<style type=\"text/css\">";
            style += "div.SETTINGS{color: blue;font-style: normal;}\n";
            style += "div.CLUSTER_TITLE{background-color: yellow; font-weight: bold;}\n";
            style += "tr.TABLE_HEADER{font-weight: bold;}\n";
            style += "tr.RESULTS_TABLE_HEADER{font-weight: bold; background:yellow}\n";
            style += "table.CLUSTER{text-align: left;}\n";
            style += "table.RESULTS{text-align: left;}\n";
            style += "td.RESULTS_ODD_ROW{text-align: left; background:rgb(240,240,255)}\n";
            style += "td.IMAGE_DATA{text-align: center;}\n";
            style += "td.IMAGE_FILELIST_DATA{text-align: left;}\n";
            style += "img.IMAGE{width: 70%}\n";
            style += "</style>\n";
            return style;

            
        }
        
        public static String settingsHtmlString(Dictionary dictionary, int stringMatchingDistance, Clustering.DistanceMeasurement distance, int numberOfClusters, String clusteringMethod)
        {
            String htmlString = "<div class=\"SETTINGS\"><br><b><u>Clustering Settings:<br></u></b>";
            htmlString += "<TABLE class=\"SETTINGS_TABLE\">";
            //DICTIONARY
            htmlString += addTableRow("DICTIONARY", "", "");
            htmlString += addTableRow("","Dictionary Size", "" + dictionary.DictionarySize);
            htmlString += addTableRow("","Dictionary word length", "" + dictionary.WordSize);
            htmlString += addTableRow("","Dictionary Source file name", "" + dictionary.SourceFileName);
            htmlString += addTableRow("","Dictionary words", "" + dictionary.ID);
            //ALPHABET SETTINGS
            htmlString += addTableRow("ALPHA BET", "", "");
            htmlString += addTableRow("","Alphbet Size", ""+dictionary.DictionaryAlphaBetSize);
            //STRING MATCHING SETTINGS
            htmlString += addTableRow("STRING MATCHING", "", "");
            htmlString += addTableRow("", "distance between words", "" + stringMatchingDistance);
            //CLUSTERING SETTINGS
            htmlString += addTableRow("CLUSTERING", "", "");
            htmlString += addTableRow("", "Clustering Method", clusteringMethod);
            htmlString += addTableRow("", "Distance method", Enum.GetName(typeof(Clustering.DistanceMeasurement), distance));
            htmlString += addTableRow("", "Number of clusters", "" +numberOfClusters);
            htmlString += "</TABLE>";
            htmlString += "</div>";
            return htmlString;
        }
        private static String htmlListOfFiles(ArrayList clusteringResults)
        {
            String htmlList = "<OL>";
            foreach (FinalProjectLogicLayer.DataPoint[] cluster in clusteringResults)
            {
                for (int i = 0; i < cluster.Length; i++)
                {
                    htmlList += "<LI>" + cluster[i].SourceFile.Substring(cluster[i].SourceFile.LastIndexOf('\\') + 1); //File name
                    htmlList += "  ["+cluster[i].Label+"]";
                }
            }
            htmlList += "</OL>";
            return htmlList;
        }
        private static String clustersHTML(String imagePath,ArrayList clusteringResults)
        {
            String htmlClustersString = "";
            int clusterNum = 1;
            foreach (FinalProjectLogicLayer.DataPoint[] cluster in clusteringResults)
            {
                String fileList = "<OL>";
                String clusterDetailsHtml = "";
                
                for (int i = 0; i < cluster.Length; i++)
                {
                    fileList += "<LI>" + cluster[i].SourceFile.Substring(cluster[i].SourceFile.LastIndexOf('\\') + 1); //File name
                    clusterDetailsHtml += cluster[i].ToHtml();
                }
                fileList += "</OL>";

                if (cluster.Length == 0) continue;
                htmlClustersString += "<br><hr><div class=\"CLUSTER_TITLE\">CLUSTER "+clusterNum +" </div><hr>";
                htmlClustersString += "<center><table border=1>";
                htmlClustersString += "<TR><TD CLASS=\"IMAGE_DATA\"><img class=\"IMAGE\" src=\" " + imagePath + "CLUSTER" + clusterNum + ".jpg\"></TD><TD CLASS=\"IMAGE_FILELIST_DATA\">" + htmlListOfFiles(clusteringResults) + "</TD></TR><br>\n";
                htmlClustersString += "<TR><TD CLASS=\"IMAGE_DATA\"><img class=\"IMAGE\" src=\" " + imagePath + "CLUSTERD" + clusterNum++ + ".jpg\"></TD><TD CLASS=\"IMAGE_FILELIST_DATA\">" + fileList + "</TD></TR><br>\n";
                htmlClustersString += "<table></center>";
                htmlClustersString += clusterDetailsHtml;
            
            }
            return htmlClustersString;
        }

        public static String addTableRow(String data1, String data2,String data3)
        {
            String htmlString = "";
            htmlString += "<TR>";
            htmlString += "<TD>";
            htmlString += data1;
            htmlString += "</TD>";
            if (data2 != null)
            {
                htmlString += "<TD>";
                htmlString += data2;
                htmlString += "</TD>";
            }
            if (data3 != null)
            {
                htmlString += "<TD CLASS=\"IMAGE_FILELIST_DATA\">";
                htmlString += data3;
                htmlString += "</TD>";
            }
            htmlString += "</TR>\n";
            return htmlString;
        }

        public static String addTableRowHeader(String data1, String data2)
        {
            String htmlString = "";
            htmlString += "<TR class=\"TABLE_HEADER\">";
            htmlString += "<TD>";
            htmlString += data1;
            htmlString += "</TD>";
            if (data2 != null)
            {
                htmlString += "<TD colspan=2>";
                htmlString += data2;
                htmlString += "</TD>";
            }

            htmlString += "</TR>\n";
            return htmlString;
        }
        public static String addTableRow(String data1, String data2)
        {
            String htmlString = "";
            htmlString += "<TR>";
            htmlString += "<TD>";
            htmlString += data1;
            htmlString += "</TD>";
            if (data2 != null)
            {
                htmlString += "<TD colspan=2>";
                htmlString += data2;
                htmlString += "</TD>";
            }

            htmlString += "</TR>\n";
            return htmlString;
        }

        public static String addTableRow(String data1)
        {
            String htmlString = "";
            htmlString += "<TR>";
            htmlString += "<TD colspan=3>";
            htmlString += data1;
            htmlString += "</TD>";

            htmlString += "</TR>\n";
            return htmlString;
        }
        /// <summary>
        /// This method appends a child node to an element
        /// </summary>
        /// <param name="xd">The xml document</param>
        /// <param name="Node">The node of the element we want to attach a child elemnt to</param>
        /// <param name="newChild">the child element to append</param>
        /// <param name="childsText">the childs element text</param>
        private static void appendChildToNode(XmlDocument xd, XmlNode Node, String newChild, String childsText)
        {
            XmlElement childElement = xd.CreateElement(newChild); //create an xml element
            XmlText childElementsText = xd.CreateTextNode(childsText); //create text for xml element
            childElement.AppendChild(childElementsText); //append address text to address node
            Node.AppendChild(childElement); //append address node to root element
        }

        private static String lastCalculatedResultsHtmlTabel = "";
        
        public static String createHtmlClusteringResultsTabel(String[,] results, String[] labels)
        {
            int numberOfLabels = labels.Length; //number of labels
            int numberOfClusters = results.GetLength(1); //number of clusters
            String htmlTabel = "<CENTER><TABLE CLASS=RESULTS BORDER=\"1\">\n";
            for (int labelNum = -1; labelNum < numberOfLabels; labelNum++) //go over all the labels (row)
            {
                if (labelNum == -1) //write labels to the coulmns
                    htmlTabel += "\t<TR CLASS=RESULTS_TABLE_HEADER>\n";
                else
                    htmlTabel += "\t<TR>\n";
                for (int clusterNum = -1; clusterNum < numberOfClusters; clusterNum++)
                {
                    if (labelNum>-1 && labelNum%2==0)
                        htmlTabel += "\t\t<TD CLASS=RESULTS_ODD_ROW>\n";
                    else
                        htmlTabel += "\t\t<TD>\n";
                    
                    if (labelNum == -1) //write labels to the coulmns
                    {
                        if (clusterNum == -1) //write label to the row
                            htmlTabel += "LABEL";
                        else
                            htmlTabel += "CLUSTER " + (clusterNum+1);
                    }
                    else
                    {

                        if (clusterNum == -1) //write label to the row
                            htmlTabel += labels[labelNum];
                        else
                        {
                            if (results[labelNum, clusterNum] != null)
                                htmlTabel += results[labelNum, clusterNum].Replace(",", "<BR>");
                            else
                                htmlTabel += "<FONT color=white>.</font> ";
                        }
                    }
                    htmlTabel += "\t\t</TD>\n";
                }
                htmlTabel += "\t</TR>\n";
            }
            htmlTabel += "</TABLE></CENTER>\n";
            lastCalculatedResultsHtmlTabel = "<BR>"+htmlTabel;

            return "<html><head>" + createStyle() + "</head><body>" + htmlTabel + "</body></html>";
        }
    }
}
